内置序列

  • 容器序列

list, tuple, collections.deque等这些序列能存放不同类型的数据

  • 扁平序列

str, byte, bytearray, memoryview, array.array, 这些序列只能容纳一种类型数据

以上,容器序列存放的是他们所含任意类型对象的引用,而扁平序列存放的是值而不是引用

列表(list)是最基础也是最重要的序列类型

列表推导

>>> symbols = '中华人民共和国'
>>> codes = [ord(symbol) for symbol in symbols]
>>> codes
[20013, 21326, 20154, 27665, 20849, 21644, 22269]

列表推导由for循环变换而来,增强可读性的同时,也使得代码更加简洁

python会忽略代码里[]/()/{}中的换行,在其中可以省略续行符 "\"

生成器表达式

生成器的语法和列表推导差不多,只是把方括号换成圆括号

>>> symbols = '中华人民共和国'
>>> tuple(ord(symbol) for symbol in symbols)
(20013, 21326, 20154, 27665, 20849, 21644, 22269)
>>> import array
>>> array.array('I', (ord(symbol) for symbol in symbols))
array('I', [20013, 21326, 20154, 27665, 20849, 21644, 22269])

(1) 如果生成器表达式是一个函数唯一的参数,那么这个参数不需要额外的括号
(2) array的构造方法需要两个参数,所以生成器表达式需要被括号围起来

list.sort方法和内置函数sorted

  • list.sort 方法的功能是将序列就地排序,即不会重新创建一个数组,将原数组复制过来
  • 与list.sort不同的是,序列的内置函数sorted的功能虽然也是排序,但是会重新创建一个数组,不会对原数组做任何改动
>>> fruits = ['grape', 'respberry', 'apple', 'banana']
>>> sorted(fruits)
['apple', 'banana', 'grape', 'respberry']
>>> fruits
['grape', 'respberry', 'apple', 'banana']
>>> sorted(fruits, key=len)
['grape', 'apple', 'banana', 'respberry']
>>> sorted(fruits, key=len, reverse=True)
['respberry', 'banana', 'grape', 'apple']
>>> fruits
['grape', 'respberry', 'apple', 'banana']
>>> fruits.sort()
>>> fruits
['apple', 'banana', 'grape', 'respberry']

由以上的例子可以看出两者的差别,而sorted函数还接受key, reverse两个参数
其中,参数key表示比较的标准,而reverse表示是否要逆序(True)

利用bisect管理有序序列

利用bisect进行搜索

函数bisect(haystack, needle)可实现在haystack(干草堆,一个有序序列)中找到needle(针)的位置,该位置满足的条件是,把needle插入该函数所搜索到的位置后,整个haystack依然保持有序

import bisect
import sys
import random


haystack = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
needles = [0, 1, 2, 5, 8, 10, 22, 23, 29, 30, 31]
row_fmt = '{0:2d} @ {1:2d}    {2}{0:<2d}'


def demo(bisect_fn):
    for needle in reversed(needles):
        position = bisect_fn(haystack, needle)
        offset = position * ' |'
        print(row_fmt.format(needle, position, offset))


if __name__ == '__main__':

    if sys.argv[-1] == 'left':
        bisect_fn = bisect.bisect_left
    else:
        bisect_fn = bisect.bisect_right

    print('Demo: ', bisect_fn.__name__)
    print('haystack ->', ''.join('%2d' % n for n in haystack))
    demo(bisect_fn)



    print("\n\n#################insort###############")
    size = 7
    # random.seed(1729)
    my_list = []
    for i in range(7):
        new_item = random.randrange(size * 2)
        bisect.insort(my_list, new_item)
        print('%2d ->' % new_item, my_list)
        
    #############运行结果################
Demo:  bisect_right
haystack ->  1 4 5 6 8121520212323262930
31 @ 14     | | | | | | | | | | | | | |31
30 @ 14     | | | | | | | | | | | | | |30
29 @ 13     | | | | | | | | | | | | |29
23 @ 11     | | | | | | | | | | |23
22 @  9     | | | | | | | | |22
10 @  5     | | | | |10
 8 @  5     | | | | |8
 5 @  3     | | |5
 2 @  1     |2
 1 @  1     |1
 0 @  0    0


#################insort###############
 9 -> [9]
 7 -> [7, 9]
 1 -> [1, 7, 9]
 4 -> [1, 4, 7, 9]
 5 -> [1, 4, 5, 7, 9]
12 -> [1, 4, 5, 7, 9, 12]
 5 -> [1, 4, 5, 5, 7, 9, 12]

*bisect其实是bisect_rihght函数的缩写,其返回的插入位置是原始序列与被插入元素相等元素位置的 右边 ,该函数还有一个姊妹函数bisect_left,其返回的插入位置是原始序列与被插入元素相等元素位置的 左边

书中还有推荐一个网站 Python Tutor , 是一个对python运行原理进行可视化分析的工具。

注: 以上内容主体均来自于《流畅的python》书中第2章 序列构成的数组


逸远尘红
1 声望2 粉丝